////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//                                                                                                                            //
//                                                         WNProject                                                          //
//                                                                                                                            //
//            This file is distributed under the BSD 2-Clause open source license. See License.txt for details.               //
//                                                                                                                            //
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

#pragma once

#ifndef __WN_MATH_INTERNAL_X86_BASIC_H__
#define __WN_MATH_INTERNAL_X86_BASIC_H__

#ifndef __WN_MATH_BASIC_H__
    #error "x86/WNBasic.h should never be included directly. Please include WNBasic.h instead"
#elif !defined _WN_X86
    #error "x86/WNBasic.h has been included on a non x86 platform. Please rectify this."
#elif !defined __WN_MATH_ENABLE_EXTENSIONS
    #error "x86/WNBasic.h has been included when extensions are disabled. Please rectify this."
#endif

namespace WNMath {
    template <> WN_FORCE_INLINE WN_FLOAT32 WNMod(const WN_FLOAT32 _dividend, const WN_FLOAT32 _divisor);
    template <> WN_FORCE_INLINE WN_FLOAT64 WNMod(const WN_FLOAT64 _dividend, const WN_FLOAT64 _divisor);

    template <> WN_FORCE_INLINE WN_FLOAT32 WNRound(const WN_FLOAT32& _number);
    template <> WN_FORCE_INLINE WN_FLOAT64 WNRound(const WN_FLOAT64& _number);

    template <> WN_FORCE_INLINE WN_FLOAT32 WNCeil(const WN_FLOAT32& _number);
    template <> WN_FORCE_INLINE WN_FLOAT64 WNCeil(const WN_FLOAT64& _number);

    template <> WN_FORCE_INLINE WN_FLOAT32 WNFloor(const WN_FLOAT32& _number);
    template <> WN_FORCE_INLINE WN_FLOAT64 WNFloor(const WN_FLOAT64& _number);

    template <> WN_FORCE_INLINE WN_FLOAT32 WNTrunc(const WN_FLOAT32& _number);
    template <> WN_FORCE_INLINE WN_FLOAT64 WNTrunc(const WN_FLOAT64& _number);

    template <> WN_FORCE_INLINE WN_FLOAT32 WNSqrt(const WN_FLOAT32& _number);
    template <> WN_FORCE_INLINE WN_FLOAT64 WNSqrt(const WN_FLOAT64& _number);

    template <> WN_FORCE_INLINE WN_FLOAT32 WNInvSqrt(const WN_FLOAT32& _number);
    template <> WN_FORCE_INLINE WN_FLOAT64 WNInvSqrt(const WN_FLOAT64& _number);

    template <> WN_FORCE_INLINE WN_FLOAT32 WNMin(const WN_FLOAT32& _first, const WN_FLOAT32& _second);
    template <> WN_FORCE_INLINE WN_FLOAT64 WNMin(const WN_FLOAT64& _first, const WN_FLOAT64& _second);

    template <> WN_FORCE_INLINE WN_FLOAT32 WNMax(const WN_FLOAT32& _first, const WN_FLOAT32& _second);
    template <> WN_FORCE_INLINE WN_FLOAT64 WNMax(const WN_FLOAT64& _first, const WN_FLOAT64& _second);

    template <> WN_FORCE_INLINE WN_FLOAT32 WNClamp(const WN_FLOAT32& _number, const WN_FLOAT32& _min, const WN_FLOAT32& _max);
    template <> WN_FORCE_INLINE WN_FLOAT64 WNClamp(const WN_FLOAT64& _number, const WN_FLOAT64& _min, const WN_FLOAT64& _max);
}

#endif // __WN_MATH_INTERNAL_X86_BASIC_H__